#include "client.h"
#define BUFSIZE 1068
 
void initclient() 
{
    loginserver();
    //将连接标志置为1
    linkFlags=1-linkFlags;
    //将STDIN文件属性修改为非阻塞
    int ops,stdinflags;
    if((ops=fcntl(STDIN_FILENO,F_GETFL,0))<0)
    {
        printf("get stdin error\n");
        exit(0);
    }
    if((stdinflags=fcntl(STDIN_FILENO,F_SETFL,ops|O_NONBLOCK))<0)
    {
        printf("set stdin error\n");
        exit(0);
    }
}
 
void loginserver()
{
    printf("Please enter the client name (no more than 20 characters):\n");
    scanf("%s",clientName);
    if((publicfifo=open(PUBLICFIFO,O_WRONLY|O_NONBLOCK))<0)
    {
        perror("open server fifo");
        exit(1);
    }
    sendsermes(0);
    char path[23]="./";
    strcat(path,clientName);
    //测试管道是否创建成功
    while(access(path,F_OK)!=0);
    if((clientfifo=open(path,O_RDONLY|O_NONBLOCK))<0)
    {
        perror("open client fifo");
    }
    printf("privatefifo created successfully\n");
}
 
void sendsermes(int mesNO)
{
    MSP msp;
    char *buf;
    msp.messageNo=mesNO;
    strcpy(msp.senderName,clientName);
    buf=(void*)&msp;
    write(publicfifo,buf,sizeof(msp));
}
 
void messagehanle(char* pMes)
{
    //将“quit”或者“exit”设置为退出消息
    if(strcmp(pMes,"quit")==0||strcmp(pMes,"exit")==0)
    {
        sendsermes(2);
        closeclient();
        return;
    }
    //发送数据格式为：接受者姓名:消息内容
    //如果数据不符合规范，则将消息转为群发。
    int i=0,j=0;
    char receiverName[20];
    char data[1024];
    while(pMes[i]!='\0'&&pMes[i]!=':')
    {
        receiverName[i]=pMes[i];
        ++i;
    }
    receiverName[i]='\0';
    if(pMes[i]==':')
    {
        //将“:”跳过
        ++i;
    }
    else
    {
        i=0;
        receiverName[0]='\0';
    }
    while(pMes[i]!='\0')
    {
       data[j++]=pMes[i++];
    }
    data[j]='\0';
    sendmessage(receiverName,data);
}
 
void sendmessage(char* receiverName,char* data)
{
    MSP msp;
    char *buf;
    msp.messageNo=1;
    strcpy(msp.senderName,clientName);
    strcpy(msp.receiverName,receiverName);
    strcpy(msp.data,data);
    buf=(void*)&msp;
    write(publicfifo,buf,sizeof(msp));
}
 
void receivermes()
{
    char buf[BUFSIZE];
    int len=read(clientfifo,buf,sizeof(MSP));
    MSP *pMes=NULL;
    pMes=(void*)buf; 
    if(len>0&&pMes->messageNo==1)
    {
 
        printf("%s:%s\n",pMes->senderName,pMes->data);
    }
    else if(len>0)
    {
        printf("system hint:%s",buf);
    }
}
 
void closeclient()
{
    //将连接标志置为0
    linkFlags=1-linkFlags;
    //关闭私有管道
    close(clientfifo);
    //关闭公共管道
    close(publicfifo);
    printf("The pipeline is closed, the client exits safely\n");
}
 
int main()
{
    initclient();
    char mesBuf[1024];
    while(linkFlags)
    {
        //scanf()默认遇空格终止scanf("%s",mesBuf)!=EOF
        if(scanf("%s",mesBuf)!=EOF)
        {
            messagehanle(mesBuf);
        } 
        receivermes();
    }
    return 0;
}